#include "MainWindow.h"

#include "DiagramEditorWidget.h"
#include "FacadeRepositoryWidget.h"
#include "ProjectEditorWidget.h"
#include "runtime/FalconDocument.h"
#include "runtime/runtime.h"
#include "utils/asserts.h"

#include <QDockWidget>
#include <QLabel>
#include <QMenuBar>
#include <QStatusBar>
#include <QToolBar>

namespace falcon {

bool curseTrackingFacade = false;
MainCentralWidget* mainCentralWidget = nullptr;

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent) {

    //  设置中心窗口
    MainCentralWidgem = new MainCentralWidget;
    setCentralWidget(MainCentralWidgem);

    //  注册全局变量
    mainCentralWidget = MainCentralWidgem;

    //  初始化并注册全局 facade 仓库
    globalFalconDocument = new FalconDocument();
    int ret = globalFalconDocument->open("/home/llj/gitee.com/libbylg/design.uml");
    Q_ASSERT(ret == 0);

    //  创建当前支持的所有的动作
    createActions();

    //  创建菜单
    createMenus();

    //  创建所有可dock窗口
    createDocks();

    //  创建工具条
    createToolBar();

    resize(600, 600);
}

MainWindow::~MainWindow() {
}

void MainWindow::registerAction(NamedAction* action) {
    Q_ASSERT(action != nullptr);
    _registerActions[action->group()][action->name()] = action;
}

NamedAction* MainWindow::actionOf(const QString& actionName) {
    QStringList names = actionName.split('.');
    Q_ASSERT(names.size() == 2);
    auto itrGroup = _registerActions.find(names[0]);
    if (itrGroup == _registerActions.end()) {
        return nullptr;
    }

    auto itrAction = itrGroup.value().find(names[1]);
    return itrAction.value();
}

void MainWindow::createActions() {
    const QIcon newIcon = QIcon::fromTheme("document-new", QIcon(":/images/new.png"));
    NamedAction* newAction = new NamedAction("document.new", newIcon, tr("&New"), this);
    newAction->setShortcuts(QKeySequence::New);
    newAction->setStatusTip(tr("Create a new file"));
    connect(newAction, &QAction::triggered, this, &MainWindow::newFile);
    registerAction(newAction);

    NamedAction* openAction = new NamedAction("document.open", tr("&Open"), this);
    openAction->setShortcuts(QKeySequence::Open);
    openAction->setStatusTip(tr("Open a exist file"));
    connect(openAction, &QAction::triggered, this, &MainWindow::openFile);
    registerAction(openAction);

    NamedAction* closeAction = new NamedAction("document.close", tr("&Open"), this);
    closeAction->setShortcuts(QKeySequence::Close);
    closeAction->setStatusTip(tr("Open a exist file"));
    connect(closeAction, &QAction::triggered, this, &MainWindow::closeFile);
    registerAction(closeAction);

    const QIcon saveIcon = QIcon::fromTheme("document-save", QIcon(":/images/save.png"));
    NamedAction* saveAction = new NamedAction("document.save", saveIcon, tr("&Save"), this);
    saveAction->setShortcuts(QKeySequence::Save);
    saveAction->setStatusTip(tr("Open a exist file"));
    connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile);
    registerAction(saveAction);

    NamedAction* saveAsAction = new NamedAction("document.save_as", tr("&Save as..."), this);
    saveAsAction->setShortcuts(QKeySequence::SaveAs);
    saveAsAction->setStatusTip(tr("Save current document to a new file name"));
    connect(saveAsAction, &QAction::triggered, this, &MainWindow::saveAsFile);
    registerAction(saveAsAction);

    NamedAction* copyAction = new NamedAction("document.copy", tr("&Copy"), this);
    copyAction->setShortcuts(QKeySequence::Copy);
    copyAction->setStatusTip(tr("Cut the selections"));
    connect(copyAction, &QAction::triggered, this, &MainWindow::copy);
    registerAction(copyAction);

    NamedAction* cutAction = new NamedAction("document.cut", tr("&Cut"), this);
    cutAction->setShortcuts(QKeySequence::Cut);
    cutAction->setStatusTip(tr("Cut the selections"));
    connect(cutAction, &QAction::triggered, this, &MainWindow::cut);
    registerAction(cutAction);

    NamedAction* pasteAction = new NamedAction("document.paste", tr("&Paste"), this);
    pasteAction->setShortcuts(QKeySequence::Paste);
    pasteAction->setStatusTip(tr("Cut the selections"));
    connect(pasteAction, &QAction::triggered, this, &MainWindow::paste);
    registerAction(pasteAction);

    const QIcon undoIcon = QIcon::fromTheme("document-undo", QIcon(":/images/undo.png"));
    NamedAction* undoAction = new NamedAction("document.undo", undoIcon, tr("&Undo"), this);
    undoAction->setShortcuts(QKeySequence::Undo);
    undoAction->setStatusTip(tr("Undo edit"));
    connect(undoAction, &QAction::triggered, this, &MainWindow::undo);
    registerAction(undoAction);

    const QIcon redoIcon = QIcon::fromTheme("document-undo", QIcon(":/images/undo.png"));
    NamedAction* redoAction = new NamedAction("document.redo", redoIcon, tr("&Redo"), this);
    redoAction->setShortcuts(QKeySequence::Redo);
    redoAction->setStatusTip(tr("Redo edit"));
    connect(redoAction, &QAction::triggered, this, &MainWindow::redo);
    registerAction(redoAction);

    NamedAction* aboutAction = new NamedAction("document.about", tr("&About"), this);
    aboutAction->setStatusTip(tr("Show about information"));
    connect(aboutAction, &QAction::triggered, this, &MainWindow::about);
    registerAction(aboutAction);

    NamedAction* showtoolAction = new NamedAction("document.tool", tr("&tool"), this);
    showtoolAction->setStatusTip(tr("Show tool"));
    connect(showtoolAction, &QAction::triggered, this, &MainWindow::showtool);
    registerAction(showtoolAction);
}

void MainWindow::createDocks() {
    facadeRepositoryWidget = new FacadeRepositoryWidget();
    QDockWidget* dockToolbox = new QDockWidget(tr("工具箱"), this);
    dockToolbox->setWidget(facadeRepositoryWidget);
    _dockWidgets[tr("工具箱")] = dockToolbox;

    projectEditorWidget = new ProjectEditorWidget();
    QDockWidget* dockProject = new QDockWidget(tr("工程管理"), this);
    dockProject->setWidget(projectEditorWidget);
    _dockWidgets[tr("工程管理")] = dockProject;

    facadeEditorWidget = new FacadeEditorWidget();
    QDockWidget* dockProperties = new QDockWidget(tr("属性编辑器"), this);
    dockProperties->setWidget(facadeEditorWidget);
    _dockWidgets[tr("属性编辑器")] = dockProject;

    addDockWidget(Qt::LeftDockWidgetArea, dockProject);
    addDockWidget(Qt::LeftDockWidgetArea, dockToolbox);
    addDockWidget(Qt::RightDockWidgetArea, dockProperties);
}

void MainWindow::createMenus() {

    QMenuBar* bar = menuBar();

    QMenu* fileMenu = bar->addMenu(tr("&File"));
    fileMenu->addAction(actionOf("document.new"));
    fileMenu->addAction(actionOf("document.open"));
    fileMenu->addAction(actionOf("document.close"));
    fileMenu->addSeparator();
    fileMenu->addAction(actionOf("document.save"));
    fileMenu->addAction(actionOf("document.save_as"));

    QMenu* editMenu = bar->addMenu(tr("&Edit"));
    editMenu->addAction(actionOf("document.undo"));
    editMenu->addAction(actionOf("document.redo"));
    editMenu->addSeparator();
    editMenu->addAction(actionOf("document.copy"));
    editMenu->addAction(actionOf("document.cut"));
    editMenu->addAction(actionOf("document.paste"));

    QMenu* helpMenu = bar->addMenu(tr("&Help"));
    helpMenu->addAction(actionOf("document.about"));
    helpMenu->addAction(actionOf("document.tool"));

    setUnifiedTitleAndToolBarOnMac(false);
}

void MainWindow::createToolBar() {
    QToolBar* fileToolBar = new QToolBar(this);
    fileToolBar->addAction(actionOf("document.new"));
    fileToolBar->addAction(actionOf("document.open"));
    fileToolBar->addAction(actionOf("document.save"));
    fileToolBar->addAction(actionOf("document.save_as"));
    addToolBar(fileToolBar);

    QToolBar* editToolBar = new QToolBar(this);
    editToolBar->addAction(actionOf("document.cut"));
    editToolBar->addAction(actionOf("document.copy"));
    editToolBar->addAction(actionOf("document.paste"));
    addToolBar(editToolBar);
}

void MainWindow::createStatusBar() {
    QStatusBar* statusBar = new QStatusBar();
    setStatusBar(statusBar);

    statusBar->addWidget(new QLabel("111"));
}

void MainWindow::newFile() {
    globalFalconDocument = new FalconDocument;
    int ret = globalFalconDocument->open("/home/llj/gitee.com/libbylg/design.uml");
    Q_ASSERT(ret == 0);

    //  关联道 Project 编辑器
    projectEditorWidget->attach(globalFalconDocument->project);
    facadeRepositoryWidget->attach(globalFalconDocument);

    //  获取第一张图
    auto diagram = globalFalconDocument->project->diagrams[0];

    //  创建该图对应的图像编辑器
    DiagramEditorWidget* editor = new DiagramEditorWidget();
    editor->attach(globalFalconDocument, globalFalconDocument->project, diagram);

    //  将新建的图像编辑器关联到主窗口的页面
    mainCentralWidget->addTab(editor, QString(diagram->name.c_str()));
}

void MainWindow::openFile() {
    this->setWindowTitle("openFile");
}

void MainWindow::closeFile() {
    this->setWindowTitle("closeFile");
}

void MainWindow::saveFile() {
    this->setWindowTitle("saveFile");
}

void MainWindow::saveAsFile() {
    this->setWindowTitle("saveAsFile");
}

void MainWindow::about() {
    this->setWindowTitle("about");
}

void MainWindow::showtool() {
    // new FacadeRepositoryWidget(this);
}

void MainWindow::copy() {
    this->setWindowTitle("copy");
}

void MainWindow::cut() {
    this->setWindowTitle("cut");
}

void MainWindow::paste() {
    this->setWindowTitle("paste");
}

void MainWindow::undo() {
    this->setWindowTitle("undo");
}

void MainWindow::redo() {
    this->setWindowTitle("redo");
}

} // namespace falcon